package fr.imag.m2pgi.m2m.geoloc.gui;

import java.awt.Button;
import java.awt.Checkbox;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Label;
import java.awt.LayoutManager;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowStateListener;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JPanel;

import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.util.tracker.ServiceTracker;

import fr.imag.m2pgi.m2m.geoloc.Lidar;
import fr.imag.m2pgi.m2m.geoloc.mqtt.publisher.PublishService;

public class MainFrame extends Frame implements Runnable, WindowStateListener {

  private Lidar lidar;
  private ServiceTracker<PublishService, PublishService> trackerPub;
  private PublishService publish;
//  private Visualizer visualizer;
  private LaserVisualizer instant;
  private Frame visuFrame, instantFrame;
  private AddMeasureListener addListener;
  private BundleContext context;
  private LayoutManager mainLayout, displayLayout, inputLayout, zLayout,
      angleLayout, buttonLayout;
  private JPanel checkboxPanel;

  private TextField ztextfield;
  private Button addButton, closebutton;
//  private CheckboxGroup angleCheckBoxGroup;
  private Checkbox minus90, minus45, zero, plus45, plus90;

  public MainFrame(BundleContext ctxt, int width, int height) {
    setSize(width, height);
    this.context = ctxt;
    mainLayout = new GridLayout(2, 2);
    setLayout(mainLayout);

//    this.visualizer = new VisuaImpl2(1000);
//    this.visuFrame = new Frame("Visu 3D");
//    this.visuFrame.setSize(400,400);
//    this.visuFrame.add((Component) visualizer);
//    this.visuFrame.setVisible(true);

    this.instant = new LaserVisualizer(100, 100);
    this.visuFrame = new Frame("Visu 2D instantanée");
    this.visuFrame.setSize(400,400);
    this.visuFrame.add(instant);
    this.visuFrame.setVisible(true);

    
    this.add(new Label("Position Z:"));
    ztextfield = new TextField("0");
    ztextfield.setSize(100, 20);
    this.add(ztextfield);

//    this.add(new Label("Angle:"));
//    checkboxPanel = new JPanel(new GridLayout(1,5));
////    angleCheckBoxGroup = new CheckboxGroup();
//    minus90 = new Checkbox("-90°");
////    minus90.setCheckboxGroup(angleCheckBoxGroup);
//    checkboxPanel.add(minus90);
//    minus45 = new Checkbox("-45°");
////    minus45.setCheckboxGroup(angleCheckBoxGroup);
//    checkboxPanel.add(minus45);
//    zero = new Checkbox("0°");
////    zero.setCheckboxGroup(angleCheckBoxGroup);
//    checkboxPanel.add(zero);
//    plus45 = new Checkbox("45°");
////    plus45.setCheckboxGroup(angleCheckBoxGroup);
//    checkboxPanel.add(plus45);
//    plus90 = new Checkbox("90°");
////    plus90.setCheckboxGroup(angleCheckBoxGroup);
//    checkboxPanel.add(plus90);
//    this.add(checkboxPanel);

    addButton = new Button("Add measure");
    addListener = new AddMeasureListener(this);
    addButton.addActionListener(addListener);
    add(addButton);
    closebutton = new Button("Close");
    closebutton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        visuFrame.setVisible(false);
        setVisible(false);
        try {
          context.getBundle().stop();
        } catch (BundleException e1) {
          // TODO Auto-generated catch block
          e1.printStackTrace();
        }
      }
    });
    add(closebutton);

    addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        visuFrame.setVisible(false);
        setVisible(false);
        try {
          context.getBundle().stop();
        } catch (BundleException e1) {
          // TODO Auto-generated catch block
          e1.printStackTrace();
        }
      }
    });
  }

  private void init() throws InterruptedException {
    System.out.println("Init...");
    ServiceTracker<Lidar, Lidar> tracker = new ServiceTracker<Lidar, Lidar>(
        context, Lidar.class, null);
    tracker.open();
    while (lidar == null) {
      lidar = tracker.waitForService(1000);
      if (lidar == null)
        System.out.println("WARNING: Did not find lidar service");
    }
    
    trackerPub = new ServiceTracker<PublishService, PublishService>(
        context, PublishService.class, null);
    trackerPub.open();
    if(publish == null) {
      publish = trackerPub.waitForService(1000);
      if (publish == null)
        System.out.println("WARNING: Did not find Publisher service");
    }
//    try {
//      lidar = new LidarSCIP20(new SCIP20(1701));
//    } catch (IOException e) {
//      // TODO Auto-generated catch block
//      e.printStackTrace();
//    }
    addListener.setPublisher(publish, trackerPub);
    System.out.println("Lidar connected");
    instant.setLaser(lidar);
    try {
      synchronized (lidar) {
        if(!lidar.isEnabled())
          lidar.enable();
      }
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
    System.out.println("Lidar enabled");
    Thread t = new Thread(instant);
    t.start();
    System.out.println("Instant view started");
    setVisible(true);
    System.out.println("Done.");
  }

  /**
   * 
   */
  private static final long serialVersionUID = 1042608470929657855L;

  public void run() {
    try {
      init();
    } catch (InterruptedException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
  
  public Lidar getLidar() {
    return lidar;
  }
  
//  public Visualizer getVisualizer() {
//    return visualizer;
//  }
  
  public Integer getZ() {
    String txt = ztextfield.getText();
    try {
      return Integer.parseInt(txt);
    } catch(NumberFormatException e) {
      return null;
    }
  }
  
  public ArrayList<Double> getAngles() {
    ArrayList<Double> res = new ArrayList<Double>(5);
    if(minus90.getState())
      res.add(-90d);
    if(minus45.getState())
      res.add(-45d);
    if(zero.getState())
      res.add(0d);
    if(plus45.getState())
      res.add(45d);
    if(plus90.getState())
      res.add(90d);
    return res;
  }
  
  public static void main(String[] args) {
    System.out.println("Start visualizer...");
    MainFrame mf = new MainFrame(null, 200, 100);
    Thread t = new Thread(mf);
    t.start();
  }

  public void windowStateChanged(WindowEvent e) {
    if(e.getNewState()==WindowEvent.WINDOW_CLOSING) {
      visuFrame.setVisible(false);
    }
    
  }
}
